package cn.yhbk.web.modules.manager.Service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.log.Log;
import cn.yhbk.web.common.exception.ApiException;
import cn.yhbk.web.modules.manager.Pojo.Entity.TbGpaFlowPath;
import cn.yhbk.web.modules.manager.Mapper.TbGpaFlowPathMapper;
import cn.yhbk.web.modules.manager.Pojo.VO.GpaFlowPath.FlowPathGet;
import cn.yhbk.web.modules.manager.Pojo.VO.GpaFlowPath.FlowPathUpdate;
import cn.yhbk.web.modules.manager.Service.ITbGpaFlowPathService;
import cn.yhbk.web.modules.ums.model.UmsRole;
import cn.yhbk.web.modules.ums.service.UmsRoleService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 绩点评定顺序 服务实现类
 * </p>
 *
 * @author 有何不可
 * @since 2023-08-05
 */
@Service
@Slf4j
public class TbGpaFlowPathServiceImpl extends ServiceImpl<TbGpaFlowPathMapper, TbGpaFlowPath> implements ITbGpaFlowPathService {

    @Autowired
    TbGpaFlowPathMapper flowPathMapper;

    @Autowired
    UmsRoleService roleService;

    @Override
    @Transactional
    public boolean updateFlowPath(FlowPathUpdate update) {
        //更新当前order后面得记录得order
        int updateOrder = flowPathMapper.updateOrder(update.getOrder(),1);

        if(updateOrder == 0){
            //查看当前order是不是表中得最后一个，最后一个，则更新失败正常,如果不是，则更新失败
            int afterCount = flowPathMapper.getAfterCount(update.getOrder());
            if(afterCount != 0){
                log.error("更新其他记录顺序失败!");
                throw new ApiException("更新失败");
            }
        }

        //插入
        TbGpaFlowPath flowPath = new TbGpaFlowPath();
        BeanUtil.copyProperties(update,flowPath);
        boolean save = false;
        try {
            save = save(flowPath);
        } catch (Exception e) {
            if(e.getCause() instanceof SQLIntegrityConstraintViolationException)throw new ApiException("角色id重复");
        }
        if(!save){
            log.error("保存插入得记录失败!");
            throw new ApiException("更新失败!");
        }
        return true;
    }

    @Override
    public List<FlowPathGet> getFlowPath() {
        QueryWrapper<TbGpaFlowPath> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbGpaFlowPath> lambda = wrapper.lambda();

        //按照order升序排序
        lambda.orderByAsc(TbGpaFlowPath::getOrder);

        //拿到顺序
        List<TbGpaFlowPath> flowPathList = list(lambda);

        //拿到所有需要得角色,并封装成map
        List<Long> roleIds = flowPathList.stream().map(TbGpaFlowPath::getRoleId).collect(Collectors.toList());
        if(roleIds.isEmpty())roleIds.add(-1L);
        List<UmsRole> umsRoles = roleService.listByIds(roleIds);
        Map<Long, UmsRole> roleMap = umsRoles.stream().collect(Collectors.toMap(UmsRole::getId, item -> item));

        return flowPathList.stream().map(item->{
            FlowPathGet flowPathGet = new FlowPathGet();
            flowPathGet.setOrder(item.getOrder());
            flowPathGet.setRole(roleMap.get(item.getRoleId()));
            return flowPathGet;
        }).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean deleteGpaFlowPath(Integer order) {
        // 删除
        int delete = flowPathMapper.deleteByOrder(order);
        if(delete == 0){
            log.error("删除记录失败!");
            throw new ApiException("删除失败!");
        }

        //更新该order后面得记录得order，使他们保持连续性
        int updateOrder = flowPathMapper.updateOrder(order, -1);
        if(updateOrder == 0){
            //查看当前order是不是表中得最后一个，最后一个，则更新失败正常,如果不是，则更新失败
            int afterCount = flowPathMapper.getAfterCount(order);
            if(afterCount != 0){
                log.error("更新其他记录顺序失败!");
                throw new ApiException("删除失败");
            }
        }
        return true;
    }

    @Override
    public boolean checkOrder(Integer order) {
        //不能小于1
        if(order < 1)return false;

        //不能大于当前顺序最后一个加一
        int afterCount = flowPathMapper.getAfterCount(1);
        if(order > afterCount+1)return false;

        return true;
    }

    @Override
    public Integer getCurrentFlow() {
        List<Long> roleId = roleService.getCurrentRoleId();
        return  getOrderByRoleId(roleId);
    }

    @Override
    public Integer getLastOrder() {
        return flowPathMapper.getLastOrder();
    }

    private Integer getOrderByRoleId(List<Long> roleId) {
        QueryWrapper<TbGpaFlowPath> wrapper = new QueryWrapper<>();
        LambdaQueryWrapper<TbGpaFlowPath> lambda = wrapper.lambda();

        lambda.in(TbGpaFlowPath::getRoleId,roleId);
        List<TbGpaFlowPath> list = list(lambda);
        list = list.stream().filter(item->!Objects.isNull(item)).collect(Collectors.toList());
        if(list.size() >1){
            log.error("一个拥有两个角色以上的账号，这多个角色不能同时在审核顺序里");
            throw new ApiException("权限错误");
        }else if(list.size() == 0){
            log.error("当前角色不在评定顺序中!roleId:{}",roleId);
            throw new ApiException("网络错误，请联系管理员!");
        }

        TbGpaFlowPath one = list.get(0);
        return one.getOrder();
    }
}
